package com.cyf.util;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.TreeMap;

/**
 * 功能：微信支付接口公用函数类
 * 详细：该类是请求、通知返回两个文件所调用的公用函数核心处理文件，不需要修改
 * Created by cage on 2017/2/22.
 */
public class WxpayCore {

    private static final Logger logger = LoggerFactory.getLogger(WxpayCore.class);

    /**
     * 对请求进行签名
     *
     * @param param 要签名的参数
     * @return
     */
    public static String sign(TreeMap<String, ?> param) {
        // 1、对参数按照key=value的格式，并按照参数名ASCII字典序排序如下
        // 2、拼接API密钥
        // 3、MD5加密转为大写
        String paramUrl = SignUtil.joinKeyValue(new TreeMap<>(param), null, "&key=" + WxpayConfig.API_SECRET, "&", true, "sign_type", "sign");
        logger.debug("微信待签名串:" + paramUrl);
        MessageDigest digestUtils = DigestUtils.getMd5Digest();
        digestUtils.update(paramUrl.getBytes());
        byte[] sign = digestUtils.digest();
        String result = Hex.encodeHexString(sign).toUpperCase();
        logger.debug("签名结果:" + result);
        return result;
    }


    /**
     * 对请求进行签名
     *
     * @param param 要签名的参数
     * @return
     */
    public static String sign(TreeMap<String, ?> param, final String apiSecret) throws UnsupportedEncodingException {
        // 1、对参数按照key=value的格式，并按照参数名ASCII字典序排序如下
        // 2、拼接API密钥
        // 3、MD5加密转为大写
        String paramUrl = SignUtil.joinKeyValue(new TreeMap<>(param),
                null, "&key=" + apiSecret, "&", true, "sign_type", "sign");
        logger.debug("微信待签名串:" + paramUrl);
        MessageDigest digestUtils = DigestUtils.getMd5Digest();
        try {
            digestUtils.update(paramUrl.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            logger.error("微信签名异常：{}", e);
            throw e;
        }
        byte[] sign = digestUtils.digest();
        String result = Hex.encodeHexString(sign).toUpperCase();
        logger.debug("签名结果:" + result);
        return result;
    }


    /**
     * 微信nonce_str生成算法
     *
     * @param bits 生成位数,选择64bit
     * @return 生成后的nonce_str
     */
    public static String nonce_str(int bits) {
        final byte[] bytes;
        try {
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            if ((bits % 8) != 0) {
                throw new IllegalArgumentException("Size is not divisible by 8!");
            }
            bytes = new byte[bits / 8];
            secureRandom.nextBytes(bytes);
            return Hex.encodeHexString(bytes);
        } catch (NoSuchAlgorithmException e) {
            logger.error("微信生成随机数异常:{}", e);
        }
        return System.currentTimeMillis() + "";
    }

}
